package martian.t1me
{
	import flash.display.*;
	import flash.events.*;
	import flash.media.Sound;
	import flash.net.*;
	import flash.utils.*;
	
	import martian.t1me.core.Sequencable;
	import martian.t1me.core.Sequence;

	public class Load extends EventDispatcher implements Sequencable
	{
		static public var PROXY:String		= "";
		
		static public const IMAGE:String 		= "image";
		static public const SWF:String 			= "swf";
		static public const TEXT:String 		= "text";
		static public const BINARY:String 		= "bin";
		static public const VARIABLES:String 	= "vars";
		static public const SOUND:String		= "sound";
		
		
		private var request:URLRequest;
		private var type:String;
		
		private var raw:* = null;
			public function get data():*
			{
				switch(type)
				{
					case IMAGE:		return Bitmap(raw);
					case SWF:		return MovieClip(raw);
					case TEXT:		return String(raw);
					case BINARY:	return ByteArray(raw);
					case VARIABLES: return URLVariables(raw);
					case SOUND:		return Sound(raw);
				}
				
				return raw
			}		
			
		public function Load(request:*, type:String, cache:Boolean = false, proxy:Boolean = false)
		{
			if (request is String) { request = new URLRequest(request); }
			else if (!request is URLRequest) { throw new ArgumentError("request argument can be String or URLRequest"); }
			
			if (proxy) { request.url = PROXY + request.url; }
			
			if (!cache)
			{
				request.url += request.url.lastIndexOf("?") == -1 ? "?" : "&";
					request.url += int(Math.random() * 0xFFFFFF).toString(16).toUpperCase();
			}
			
			this.request = request;
			this.type = type;
		}
		
		public function load():void { start(); }
		
		public function start():void
		{
			var loader:*;
			
			switch(type)
			{
				case IMAGE: case SWF:
					loader = new Loader();
						loader.contentLoaderInfo.addEventListener(Event.COMPLETE, stop);
						loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progress);
						loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, stop);
						break;
				
				case TEXT: case BINARY: case VARIABLES:
					loader = new URLLoader();
						loader.addEventListener(Event.COMPLETE, stop);
						loader.addEventListener(ProgressEvent.PROGRESS, progress);
						loader.addEventListener(IOErrorEvent.IO_ERROR, stop);
						break;
				
				case SOUND:
					loader = new Sound();
						loader.addEventListener(Event.COMPLETE, stop);
						loader.addEventListener(ProgressEvent.PROGRESS, progress);
						loader.addEventListener(IOErrorEvent.IO_ERROR, stop);
						break;
				
				default:
					throw new Error("unknown loader type:" + type);
					stop();
					return;
			}
			
			loader.load(request);
			dispatchEvent(new Event(Sequence.START));
		}
		
		private function progress(e:ProgressEvent):void { dispatchEvent(e.clone()); }
		
		private function stop(e:* = null):void
		{
			if (e != null)
			{
				e.target.removeEventListener(Event.COMPLETE, stop);
				e.target.removeEventListener(ProgressEvent.PROGRESS, progress);
				e.target.removeEventListener(IOErrorEvent.IO_ERROR, stop);
				
				if (e.type == Event.COMPLETE)
				{
					switch(type)
					{
						case IMAGE: case SWF:
							raw = e.target.content;
							break;
						
						case TEXT: case BINARY: case VARIABLES:
							raw = e.target.data;
							break;
						
						case SOUND:
							raw = e.target;
							break;
					}
					
					dispatchEvent(new Event(Event.COMPLETE));
				}
				else
				{
					dispatchEvent(new IOErrorEvent(IOErrorEvent.IO_ERROR));
				}
			}
			
			dispatchEvent(new Event(Sequence.STOP));
		}
	}
}